

<template>
  <div class="search_bar" :class="customClass" :data-t-id="searchPlanId" ref="searchBarBox">
    <!-- qf_input -->
    <div class="search_bar_header">
      <div class="search_wrap">
        <!-- 输入框快捷搜索 -->
 
        <div class="serach_input" v-show="!closeEnter" >
          <!-- @blur="showTips(false)" -->
          <el-input
            ref="toolInput"
            class="serach_input_border"
            @keyup.enter="searchMethods($event, 'enter')"
            type="text"
            :placeholder="placeholder"
            v-model.trim="searchVal"
            @clear="searchMethods($event, 'enter')"
            @focus="showTips(true)"
            @blur="showTips(false)"
            clearable
          >
            <template #suffix>
              <div
                class="search_btn"
                @click="searchMethods($event, 'enter')"
                v-popover="popoverRef"
                v-click-outside="onClickOutside"
              >
                <el-icon class="el-input__icon">
                  <search />
                </el-icon>
              </div>
            </template>
          </el-input>
        </div>
     
        <slot name="custom_filter"></slot>
        <!-- 选择搜索方案 -->

        <div class="search_plan" v-if="!closeAdvanced && !closePlan">
          <el-select
            class="search_plan_select"
            clearable
            :placeholder="$t('merak.plan_select_placeholder')"
            style="width: 200px"
            v-model="planValue"
            @change="searchMethods($event, 'plan')"
          >
            <el-option v-for="item_option in planOptions" :key="item_option" :label="item_option.name" :value="item_option.id" />
          </el-select>
        </div>
        <!-- 选择搜索方案 -->

        <!-- 高级搜索按钮 -->
        <!-- :visible="popoverVisible" -->
        <!-- @show="showAdvancedModal" -->
        <el-popover
          popper-class="advanced-modal"
          transition="el-zoom-in-top"
          :visible="popoverVisible"
          :offset="popoverOffset"
          placement="bottom"
          :popper-style="popperStyle"
          trigger="click"
          ref="searchPopverRef"
        >
          <template #reference>
            <div ref="filterBtnRef" :title="$t(`merak.search_list_ad`)">
              <el-button
                type="default"
                class="filter_btn advanced-modal-button"
                :class="{ active: popoverVisible }"
                v-if="!closeAdvanced"
                @click="showAdvancedModal"
              >
                <el-icon><Filter /></el-icon>
              </el-button>
            </div>
          </template>
          <!-- 高级搜索弹框插槽 -->
          <div class="modal" ref="popoverModalFef">
            <slot name="searchForm" :closePlan="!closePlan"></slot>
          </div>
          <!-- 高级搜索弹框插槽 -->
        </el-popover>
        <!-- 高级搜索按钮 -->
        <div class="search_params_num" v-if="selectedNumVal != 0 && !closeAdvanced">
          {{ $t("merak.search_been") }}<span class="selected_num">{{ selectedNumVal }}</span
          >{{ $t("merak.search_selected") }}
          <el-icon class="quick_rest_earch" @click="quickRestEarch"><CircleCloseFilled /></el-icon>
        </div>
      </div>
      <slot name="header"></slot>
    </div>
    <div class="search_bar_body">
      <slot name="body"></slot>
    </div>
    <div class="search_bar_footer">
      <div class="search_bar_tools">
        <slot name="footer"></slot>
      </div>
    </div>

    <searchPlan
      ref="searchplan"
      :cur-id="searchPlanId"
      :val-key="planKey"
      :form-data="formData"
      v-model="modelValue"
      :plan-options="planOptions"
      @saveplan="savePlanMethods"
    ></searchPlan>

    <el-tooltip popper-class="search_bar_tooltips" :visible="tooltipVisible" virtual-triggering :virtual-ref="toolInput">
      <template #content>
        <span>{{ placeholder }}</span>
      </template>
    </el-tooltip>
  </div>
</template>
<script setup lang="ts">
// 搜索框和高级搜索互相覆盖

import { ref, unref, defineProps, onMounted, toRefs, watchEffect, watch, defineExpose, onUnmounted, nextTick } from "vue";
import { ElMessage, ClickOutside as vClickOutside } from "element-plus";
import searchPlan from "@/components/SearchBar/components/searchPlan.vue";
import SelectedParams from "@/components/SearchBar/components/selectedParams.vue";
import { PORT1 } from "@/api/config/servicePort";
import { ResultEnum } from "@/enums/httpEnum";
import http from "@/api";
import optionsList from "./interface";
import bus from "./bus";
import { propsInterFace } from "./index";
import { active } from "sortablejs";
import { cos } from "mathjs";
const popoverRef = ref();

let $emit = defineEmits<{
  (event: "searchEvent", val: any): void;
}>();

const modelValue = defineModel<object>({ default: {} });

const props = defineProps({
  customClass: {
    type: String,
    default: ""
  },
  planOptions: {
    //搜索计划方案下拉数据
    type: Array,
    default: () => []
  },
  placeholder: {
    //input框placeholder
    type: String,
    default: "请输入..."
  },
  searchValue: {
    // 快速搜索 默认值
    type: String,
    default: ""
  },
  planValue: {
    //当前使用的搜索计划
    type: String,
    default: ""
  },
  planKey: {
    type: String,
    default: "value"
  },
  modalShow: {
    //显示高级搜索模态框
    type: Boolean,
    default: false
  },
  closeEnter: {
    //显示 快速搜索模块
    type: Boolean,
    default: false
  },
  closePlan: {
    //显示 搜索计划模块
    type: Boolean,
    default: false
  },
  closeAdvanced: {
    //显示高级搜索
    type: Boolean,
    default: false
  },
  searchName: {
    //搜索参数key，支持自定义
    type: String,
    default: "search"
  },
  planName: {
    //计划参数key，支持自定义
    type: String,
    default: "plan"
  },
  formData: {
    type: Object,
    default: {}
  }
});

let { closeEnter, closePlan, closeAdvanced, searchName, planName, planKey } = toRefs(props);

let planOptions = ref<optionsList>([]);
let searchVal = ref<string>("");
let planValue = ref<string>("");
let searchPlanId = ref<string>("");
let searchBarBox = ref<any>(null); //搜索模块元素
const searchplan = ref<HTMLElement | null>(null); //serachPlan 的ref element

//高搜索弹出框
let popoverOffset: number = 8; //默认向上偏移量
let popoverVisible = ref<boolean>(props.modalShow); //搜索弹出框值
let popperStyle = ref<object>({}); //默认弹出框宽自定义样式 ，禁止设置top值
let filterBtnRef = ref();
let searchPopverRef = ref();
let popoverModalFef = ref();

const tooltipVisible = ref(false);
const toolInput = ref();
const showTips = isShow => {
  // console.log(isShow);visible
  tooltipVisible.value = isShow;
};

//高搜索弹出框
let timer = null;
//life
onMounted(() => {
  //高搜索弹出框 挂载后设置 width和 left
  setAdvancedModalStyle();
  window.addEventListener("resize", handleResize);
});

onUnmounted(() => {
  window.removeEventListener("resize", handleResize);
});
// methods
const handleResize = () => {
  clearTimeout(timer);
  timer = setTimeout(() => {
    setAdvancedModalStyle();
  }, 100);
};
const curAttr = ref<string>("");
const labelClass = ref<string>("");
const onClickOutside = e => {

 

  function getall() {
   
    return Promise.all([
      getParents(e.target),
      getEleLabel(e.target),
      getAttr(e.target),
      getPopperAttr(e.target),
      getOwnPopperAttr(e.target)
    ]);
  }
  getall().then(res => {
    let info = {
      in: res[0],
      labelClass: res[1],
      pAttr: res[2],
      popperAttr: res[3],
      ownPopperClass: res[4]
    };

    if (info.ownPopperClass) {
      //如果包含 own_poper_class 说明是在表单里，不关闭
      return;
    }
    if (info.in) {
      //父级id在盒子了，
      curAttr.value = info.pAttr || "e3";
      labelClass.value = info.labelClass; //存储当元素的class
    }
    if (!info.in) {
      if (labelClass.value == "el-form-item__label") {
        //如果等于 label的class 说明是通过label激发的
        return;
      }
      if (curAttr.value == info.popperAttr) {
        // 否则通过id来判断 当前的poper id是不是父元素的 attr
        //是一个盒子
        return;
      } else {
        document.removeEventListener("keydown", tabfn);
        popoverVisible.value = false;
      }
    }
  });
};

//已选条件数量
const selectedNumVal = ref(0);
const selectedNum = formData => {
  selectedNumVal.value = 0;
  Object.values(formData).map(item => {
    let val = item.value;

    if (typeof val !== "undefined" && val !== null && val !== "" && val?.length != 0) {
      selectedNumVal.value++;
    }
  });
};
const quickRestEarch = () => {
  setFormValue([]);
  searchMethods("", "enter");
};

//增加点击外围 收起模态框功能
const getParents = ele => {
  let reg = /(advanced\-modal)|(advanced\-modal\-button)|(search_plan)|(search_params_num)/gi;
  if (!ele?.parentNode) {
    return Promise.resolve(false);
  }
  if (reg.test(ele.className)) {
    return Promise.resolve(true);
  } else {
    return getParents(ele.parentNode);
  }
};
const getEleLabel = ele => {
  return Promise.resolve(ele.className);
};
//查找当前元素的attr
const getAttr = ele => {
  let reg = /(el\-popper)/gi;
  function get(ele) {
    let attr = "",
      id = "";
    if (!ele?.parentNode) {
      return false;
    }
    attr = ele.getAttribute("aria-describedby") || ele.getAttribute("aria-controls");

    if (attr) {
      return attr;
    } else {
      return get(ele.parentNode);
    }
  }

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let attrName = get(ele);
      resolve(attrName);
    }, 60);
  });
};

//查找父级元素 是 poper 类名的 id
const getPopperAttr = ele => {
  let reg = /(el\-popper)/gi;
  function get(ele) {
    let attr = "",
      id = "";
    if (!ele?.parentNode) {
      return false;
    }

    if (reg.test(ele.className)) {
      return ele.id;
    } else {
      return get(ele.parentNode);
    }
  }

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let attrName = get(ele);
      resolve(attrName);
    }, 60);
  });
};
//查找父级元素 是 own_popper 类名的
const getOwnPopperAttr = ele => {
  let reg = /(own\_popper)/gi;
  function get(ele) {
    let attr = "",
      id = "";
    if (!ele?.parentNode) {
      return false;
    }
    if (reg.test(ele.className)) {
      return true;
    } else {
      return get(ele.parentNode);
    }
  }

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let attrName = get(ele);
      resolve(attrName);
    }, 60);
  });
};
const getOffsetBody = (ele: any) => {
  let curEle = ele;
  let leftVal: number = 0;
  let topVal: number = 0;
  while (curEle.offsetParent) {
    leftVal += curEle.offsetLeft;
    topVal += curEle.offsetTop;
    curEle = curEle.offsetParent;
  }
  return { left: leftVal, top: topVal };
};

const searchMethods = (event, type) => {
  let deepPlanOptions = JSON.parse(JSON.stringify(planOptions.value)),
    index = 0;

  if (deepPlanOptions) {
    index = deepPlanOptions.findIndex(item => item.id == planValue.value);
  }
  if (type === "enter") {
    planValue.value = "";
    popoverVisible.value = false;
    setFormValue([]);
  }
  if (type === "plan") {
    searchVal.value = "";
    popoverVisible.value = false;

    if (index == -1) {
      console.log("没有拿到数据，重置表单");
      setFormValue([]);
    }

    if (index != -1) {
      setFormValue(deepPlanOptions[index]);
    }
  }

  $emit("searchEvent", {
    [searchName.value]: searchVal.value,
    [planName.value]: planValue.value,
    params: (deepPlanOptions ? deepPlanOptions[index]?.params : {}) ?? {},
    action: type
  });
};

//点击方案后 同步表单 ,清空表单内容页使用这个

const setFormValue = selected => {
  let selectedList = JSON.parse(JSON.stringify(selected));

  if (Object.keys(selected).length == 0) {
    let modelVal = { ...modelValue.value };
    Object.keys(modelVal).map(key => {
      // const value = { ...modelValue.value };
      modelVal[key].value = undefined;
    });
    modelValue.value = modelVal;
    return;
  }
  let copyVal = { ...modelValue.value };
  Object.keys(copyVal).map(formKey => {
    //这里判断 表单的options有没有值，有，则不写入方案存储的数据，空数组则写入 方案options数据，暂时不考虑翻译的问题

    if (!copyVal[formKey]["options"]) {
      copyVal[formKey]["options"] = [];
    }
    if (!selected.params[formKey + "_options"]) {
      selected.params[formKey + "_options"] = [];
    }

    if (selected.params[formKey + "_options"].length && copyVal[formKey]["options"].length == 0) {
      copyVal[formKey]["options"] = [...selected.params[formKey + "_options"]];
    }
    copyVal[formKey].value = selected.params[formKey]; //设置 value值
    copyVal[formKey]["text"] = selected.params[formKey + "_text"];
  });

  modelValue.value = copyVal;
};

const setAdvancedModalStyle = () => {
  let offset = getOffsetBody(searchBarBox.value);

  let btnOffset = getOffsetBody(filterBtnRef.value);
  popperStyle.value = {
    left: offset.left + "px",
    width: searchBarBox.value.clientWidth + "px",
    height: document.documentElement.clientHeight - offset.top - searchBarBox.value.clientHeight - 50 + "px"
  };
  nextTick(() => {
    setTimeout(() => {
      popoverModalFef.value.parentNode.querySelector(".el-popper__arrow").style.left =
        btnOffset.left - offset.left + (filterBtnRef.value.clientWidth / 2 - 8) + "px";
    });
  });
  // console.log(popoverModalFef.value )
};
//clear清空 输入框和 计划选中

const clear = () => {
  searchVal.value = "";
  planValue.value = "";
};
function tabfn(event) {
  if (event.key === "Tab") {
    event.preventDefault();
    return false;
  }
}

//高级搜索弹框打开
const showAdvancedModal = () => {
  popoverVisible.value = !popoverVisible.value;

  document.addEventListener("keydown", tabfn);
  // bus.planOptions = planOptions;
  setAdvancedModalStyle();
};

// 获取搜索方案
const getPlanList = async id => {
  if (id) {
    searchPlanId.value = id;
    await http
      .post(PORT1 + `/api/user-search-config`, { table_id: searchPlanId.value }, { cancel: false, loading: false })
      .then(res => {
        if (res.code == ResultEnum.SUCCESS) {
          bus.planList[id] = res.data;
          planOptions.value = res.data;
        }
      });
  }
};

//保存或替换搜索方案
const savePlan = data => {
  let params = JSON.parse(JSON.stringify(data));

  http
    .post(PORT1 + `/api/save-search-config`, { table_id: searchPlanId.value, data: params }, { cancel: false, loading: false })
    .then(async res => {
      if (res.code == ResultEnum.SUCCESS) {
        ElMessage({
          message: "方案保存成功",
          type: "success",
          customClass: "messageIndex"
        });

        await getPlanList(searchPlanId.value);
        planValue.value = params.id;
        await searchMethods("", "plan");
        await searchplan.value?.closeModal();
      } else {
        ElMessage({
          message: "方案保存失败",
          type: "error",
          customClass: "messageIndex"
        });
      }
    });
};

const savePlanMethods = params => {
  savePlan(params);
};

//watcher
watchEffect(() => {
  // searchVal.value = props.searchValue;不在接收传递props
  // planValue.value = props.planValue; 不在接收传递props
  // planOptions.value = props.planOptions; 不在接收传递props
  selectedNum(modelValue.value);
});

//暴露方法属性

defineExpose({
  modalHide: () => {
    popoverVisible.value = false;
    document.removeEventListener("keydown", tabfn);
    document.body.click();
  },
  getPlanList,
  savePlan,
  planOptions: planOptions.value,
  clear,
  showPlanModal: () => {
    searchplan.value.showModal();
  },
  formParams: valueName => {
    let params = {};
    Object.keys(modelValue.value).map(item => {
      params[item] = modelValue.value[item][valueName];
    });
    // formData
    return params;
  }
});

bus.planOptions = planOptions;
bus.planValue = planValue;
bus.savePlan = savePlan;
// bus.planModalVisb = planModalVisb;
</script>

<style lang="scss" scoped>
$border_color: "#E7E7EF";
.search_bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0px 0px;
  background: --el-bg-color;
  // border: 1px solid #000;
  .search_bar_header {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    // gap: 10px;
    .search_btn {
      cursor: pointer;
    }

    .serach_input {
      display: flex;
      justify-content: center;
      align-items: flex-end;
    }
    .filter_btn {
      padding: 15px;
      min-width: 32px;
      width: 32px;
      font-size: 19px;
      color: var(--el-button-disabled-text-color);
      &:hover {
        //  custom
        color: var(--el-button-hover-text-color) !important;
      }
      &:focus,
      &:active {
        color: var(--el-button-disabled-text-color) !important;
      }

      &.active {
        //  custom
        color: var(--el-button-hover-text-color) !important;
        border-color: var(--el-button-hover-border-color) !important;
        background-color: transparent;
      }
    }
    .search_wrap {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 10px;
    }
  }
  .search_bar_body {
    flex: 1;
  }
  :global(.advanced-modal.el-popover.el-popper) {
    padding: 0px !important;
  }
  :deep(.search_plan_select) {
    .el-select__placeholder {
      font-size: 13px;
    }
  }
}
.advanced-modal.el-popover.el-popper {
  padding: 0px;
  .modal {
    overflow: hidden;
    height: 100%;
  }
}
.messageIndex {
  z-index: 3000 !important;
}
.search_params_num {
  display: flex;
  align-items: center;
  justify-content: start;
  color: #afafaf;
}
.quick_rest_earch {
  margin-left: 3px;
  cursor: pointer;
}
.selected_num {
  padding: 0px 2px;
  color: #e74c3d;
}


</style>
<!-- <style  >
.search_bar_tooltips {
  opacity: 0.8 !important;
}
</style> -->
